﻿// <copyright file="BlogEntryDymanicNodeProvider.cs" company="Clever Software">
// Copyright (c) 2013, 2014 All Right Reserved, http://www.cleversoftware.by
//
// This source is subject to the Microsoft Permissive License.
// Please see the License.txt file for more information.
// All other rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// </copyright>
// <author>Clever Software</author>
// <email>info@cleversoftware.by</email>
// <date>2014-02-04</date> 
// <summary>CleverCMS source code</summary>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Caching;
using CleverCMS.Services;
using CleverCMS.Web.Core.AppCache;
using CleverCMS.Web.Core.IoC;
using MvcSiteMapProvider;

namespace CleverCMS.Services.Infrastructure
{
    #region Public: Pages

    public class PagesDymanicNodeProvider : DynamicNodeProviderBase
    {
        private PageService _pagesService;
        private readonly AppCache appCache;

        public PagesDymanicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("Pages"))
                return (List<DynamicNode>)appCache.Get("Pages");

            _pagesService = IoC.Get<PageService>();
            var nodes = new List<DynamicNode>();

            var pages = _pagesService.LoadAll();
            foreach (var page in pages)
            {
                var pageNode = new DynamicNode { Key = "page_" + Guid.NewGuid(), Title = page.PageTitle };
                pageNode.RouteValues.Add("name", page.Alias);
                pageNode.Action = "Content";
                pageNode.Controller = "Home";
                nodes.Add(pageNode);
            }

            appCache.Add("Pages", nodes);
            return nodes;
        }
    }

    #endregion

    #region Public: Blog posts

    public class BlogEntryDymanicNodeProvider : DynamicNodeProviderBase
    {
        private BlogEntryService _blogEntryService;
        private readonly AppCache appCache;

        public BlogEntryDymanicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("BlogEntries"))
                return (List<DynamicNode>)appCache.Get("BlogEntries");

            _blogEntryService = IoC.Get<BlogEntryService>();
            var nodes = new List<DynamicNode>();

            // Main sitemap
            int entitiesCount = _blogEntryService.GetAll().Count();
            int pagesCount = entitiesCount % 2 == 0 ? entitiesCount / 2 : (entitiesCount + 1) / 2;
            for (int i = 0; i <= pagesCount; i++)
            {
                var entryNode = new DynamicNode { Key = "mainEntry_" + Guid.NewGuid() };
                if (i != 0)
                {
                    entryNode.RouteValues.Add("page", i);
                }
                entryNode.Action = "Index";
                entryNode.Controller = "blog";
                entryNode.Title = "All";
                nodes.Add(entryNode);
            }

            // Sitemap for categories and entry
            var categories = _blogEntryService.GetAllCategories().ToList();
            foreach (var category in categories)
            {
                int count = _blogEntryService.GetAll().Count(x => x.CategoryId == category.Id);
                for (int i = 0; i <= count; i++)
                {
                    var categoryNode = new DynamicNode { Key = "category_" + Guid.NewGuid(), Title = category.CategoryName };
                    if (i != 0)
                    {
                        categoryNode.RouteValues.Add("page", i);
                    }
                    categoryNode.RouteValues.Add("category", category.Alias);
                    categoryNode.Action = "Index";
                    categoryNode.Controller = "Blog";
                    nodes.Add(categoryNode);

                    var categoryEntries = _blogEntryService.GetAll().ToList();
                    if (categoryEntries.Any())
                    {
                        foreach (var entry in categoryEntries)
                        {
                            var entryNode = new DynamicNode { Key = "entry_" + Guid.NewGuid(), ParentKey = categoryNode.Key };
                            entryNode.RouteValues.Add("category", category.Alias);
                            entryNode.RouteValues.Add("id", entry.HeaderUrl);
                            entryNode.Action = "Entry";
                            entryNode.Controller = "blog";
                            entryNode.Title = entry.Header;
                            nodes.Add(entryNode);
                        }
                    }
                }
            }

            appCache.Add("BlogEntries", nodes);
            return nodes;
        }
    }

    #endregion

    public class TagsDymanicNodeProvider 
        : DynamicNodeProviderBase 
    {
        private BlogEntryService _blogEntryService;
        private PageService _pageService;
        private readonly AppCache appCache;

        public TagsDymanicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("Tags"))
                return (List<DynamicNode>)appCache.Get("Tags");

            _blogEntryService = IoC.Get<BlogEntryService>();
            _pageService = IoC.Get<PageService>();
            var nodes = new List<DynamicNode>();

            var tags = _blogEntryService.GetAllTags().ToList();
            foreach (var tag in tags)
            {
                int count = _pageService.GetTagCount(tag.Id);
                for (int i = 0; i <= count; i++)
                {
                    var tagNode = new DynamicNode { Key = "tag_" + Guid.NewGuid(), Title = tag.Name };
                    tagNode.RouteValues.Add("tag", tag.Name);
                    if (i != 0)
                    {
                        tagNode.RouteValues.Add("page", i);
                    }
                    tagNode.Action = "Index";
                    tagNode.Controller = "Blog";
                    nodes.Add(tagNode);    
                }       
            }

            appCache.Add("Tags", nodes);
            return nodes;
        }
    }

    public class CategoriesDynamicNodeProvier 
        : DynamicNodeProviderBase
    {
        private BlogEntryService _blogEntryService;
        private readonly AppCache appCache;

        public CategoriesDynamicNodeProvier()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("Categories"))
                return (List<DynamicNode>)appCache.Get("Categories");

            _blogEntryService = IoC.Get<BlogEntryService>();
            var nodes = new List<DynamicNode>();
            var categories = _blogEntryService.GetAllCategories().ToList();
            foreach (var category in categories)
            {
                var categoryNode = new DynamicNode {Key = "category_" + Guid.NewGuid(), Title = category.CategoryName};
                categoryNode.RouteValues.Add("category", category.Alias);
                categoryNode.Action = "Index";
                categoryNode.Controller = "Blog";
                nodes.Add(categoryNode);
            }

            appCache.Add("Categories", nodes);
            return nodes;
        }
    }

    public class AdminDynamicNodeProvider 
        : DynamicNodeProviderBase
    { 
        private BlogEntryService _blogEntryService;
        private readonly AppCache appCache;

        public AdminDynamicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("AdminBlogEntries"))
                return (List<DynamicNode>)appCache.Get("AdminBlogEntries");

            _blogEntryService   = IoC.Get<BlogEntryService>();
            var nodes           = new List<DynamicNode>();

            var entries = _blogEntryService.GetAll().ToList();
            foreach (var entry in entries)
            {
                var pageNode = new DynamicNode {Key = "entry_" + Guid.NewGuid() + "_" + entry.Id, Title = entry.Header};
                pageNode.RouteValues.Add("id", entry.Id);
                pageNode.Action = "Edit";
                pageNode.Controller = "Blog";
                pageNode.Area = "Admin";
                nodes.Add(pageNode); 
            }

            //Edit categories 
            var categories = _blogEntryService.GetAllCategories().ToList();
            foreach (var category in categories)
            {
                var categoryNode = new DynamicNode
                {
                    Key = "category_" + Guid.NewGuid() + "_" + category.Id,
                    Title = category.CategoryName
                };
                categoryNode.RouteValues.Add("id", category.Id);
                categoryNode.Action = "EditCategory";
                categoryNode.Controller = "Blog";
                categoryNode.Area = "Admin";
                nodes.Add(categoryNode);
            }

            appCache.Add("AdminBlogEntries", nodes);
            return nodes;
        }
    }

    public class AdminPagesDymanicNodeProvider
       : DynamicNodeProviderBase
    {
        private PageService _pagesService;
        private readonly AppCache appCache;

        public AdminPagesDymanicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("AdminPages"))
                return (List<DynamicNode>)appCache.Get("AdminPages");

            _pagesService = IoC.Get<PageService>();
            var nodes = new List<DynamicNode>();

            var pages = _pagesService.LoadAll();
            foreach (var page in pages)
            {
                var pageNode = new DynamicNode { Key = "page_" + Guid.NewGuid(), Title = page.PageTitle };
                pageNode.RouteValues.Add("id", page.Id);
                pageNode.Action = "Edit";
                pageNode.Controller = "Page";
                pageNode.Area = "Admin";
                nodes.Add(pageNode);
            }

            appCache.Add("AdminPages", nodes);
            return nodes;
        }
    }

    public class AdminSettingsDymanicNodeProvider  
       : DynamicNodeProviderBase
    {
        private SettingService _settingService;
        private readonly AppCache appCache;

        public AdminSettingsDymanicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("AdminSettings"))
                return (List<DynamicNode>)appCache.Get("AdminSettings");

            _settingService = IoC.Get<SettingService>();
            var nodes = new List<DynamicNode>();

            var settings = _settingService.LoadAll().ToList();
            foreach (var setting in settings)
            {
                var settingNode = new DynamicNode
                {
                    Key = "setting_" + Guid.NewGuid() + "_" + setting.Id,
                    Title = setting.Key
                };
                settingNode.RouteValues.Add("id", setting.Id);
                settingNode.Action = "Edit";
                settingNode.Controller = "Settings";
                settingNode.Area = "Admin";
                nodes.Add(settingNode);
            }

            appCache.Add("AdminSettings", nodes);
            return nodes;
        }
    }

    #region Admin: Menu & MenuItems providers

    public class MenusDymanicNodeProvider
       : DynamicNodeProviderBase
    {
        private MenuItemService _menuItemService;
        private readonly AppCache appCache;

        public MenusDymanicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("AdminMenus"))
                return (List<DynamicNode>)appCache.Get("AdminMenus");

            _menuItemService = IoC.Get<MenuItemService>();
            var nodes = new List<DynamicNode>();

            var categories = _menuItemService.LoadMenues().ToList();
            foreach (var category in categories)
            {
                var categoryNode = new DynamicNode
                {
                    Key = "menus_" + Guid.NewGuid() + "_" + category.Id,
                    Title = category.Description
                };
                categoryNode.RouteValues.Add("id", category.Id);
                categoryNode.Action = "List";
                categoryNode.Controller = "MenuItem";
                categoryNode.Area = "Admin";
                nodes.Add(categoryNode);

                if (_menuItemService.LoadAllMenuItems().Any(x=>x.MenuId == category.Id))
                {
                    var menuItems = _menuItemService.LoadAllMenuItems().Where(x => x.MenuId == category.Id).ToList();
                    foreach (var menuItem in menuItems)
                    {
                        var menuItemNode = new DynamicNode
                        {
                            Key = "menuItem_" + Guid.NewGuid() + "_" + menuItem.Id,
                            Title = menuItem.Title
                        };
                        menuItemNode.RouteValues.Add("id", menuItem.Id);
                        menuItemNode.ParentKey = categoryNode.Key;
                        menuItemNode.Action = "Edit";
                        menuItemNode.Controller = "MenuItem";
                        menuItemNode.Area = "Admin";
                        nodes.Add(menuItemNode);
                    }
                }
            }

            appCache.Add("AdminMenus", nodes);
            return nodes;
        }
    }

    #endregion

    #region Admin: Users

    public class UsersDynamicNodeProvider : DynamicNodeProviderBase
    {
        private AccountService _accountService;
        private readonly AppCache appCache;

        public UsersDynamicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("Users"))
                return (List<DynamicNode>)appCache.Get("Users");

            _accountService = IoC.Get<AccountService>();
            var nodes = new List<DynamicNode>();

            var users = _accountService.LoadAllUsers().ToList();
            foreach (var user in users)
            {
                var userNode = new DynamicNode { Key = "user_" + Guid.NewGuid() + "_" + user.Id, Title = user.Name };
                userNode.RouteValues.Add("id", user.Id);
                userNode.Action = "Edit";
                userNode.Controller = "Accounts";
                userNode.Area = "Admin";
                nodes.Add(userNode);
            }

            appCache.Add("Users", nodes);
            return nodes;
        }
    }

    #endregion

    #region Admin: Roles

    public class RolesDynamicNodeProvider : DynamicNodeProviderBase 
    {
        private AccountService _accountService;
        private readonly AppCache appCache;

        public RolesDynamicNodeProvider()
        {
            this.appCache = new AppCache();
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            if (appCache.Exists("Roles"))
                return (List<DynamicNode>)appCache.Get("Roles");

            _accountService = IoC.Get<AccountService>();
            var nodes = new List<DynamicNode>();

            var roles = _accountService.LoadAllRoles().ToList();
            foreach (var role in roles)
            {
                var roleNode = new DynamicNode
                {
                    Key = "role_" + Guid.NewGuid() + "_" + role.RoleId,
                    Title = role.RoleName
                };
                roleNode.RouteValues.Add("id", role.RoleId);
                roleNode.Action = "Edit";
                roleNode.Controller = "Role";
                roleNode.Area = "Admin";
                nodes.Add(roleNode);
            }

            appCache.Add("Roles", nodes);
            return nodes;
        }
    }

    #endregion
}